home *** CD-ROM | disk | FTP | other *** search
/ Mac Easy 2010 May / Mac Life Ubuntu.iso / casper / filesystem.squashfs / usr / lib / python2.6 / dist-packages / PIL / TiffImagePlugin.pyc (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2009-04-20  |  20.8 KB  |  710 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.6)
  3.  
  4. __version__ = '1.3.5'
  5. import Image
  6. import ImageFile
  7. import ImagePalette
  8. import array
  9. import string
  10. import sys
  11.  
  12. try:
  13.     if sys.byteorder == 'little':
  14.         byteorder = 'II'
  15.     else:
  16.         byteorder = 'MM'
  17. except AttributeError:
  18.     if ord(array.array('i', [
  19.         1]).tostring()[0]):
  20.         byteorder = 'II'
  21.     else:
  22.         byteorder = 'MM'
  23. except:
  24.     ord(array.array('i', [
  25.         1]).tostring()[0])
  26.  
  27.  
  28. def il16(c, o = 0):
  29.     return ord(c[o]) + (ord(c[o + 1]) << 8)
  30.  
  31.  
  32. def il32(c, o = 0):
  33.     return ord(c[o]) + (ord(c[o + 1]) << 8) + (ord(c[o + 2]) << 16) + (ord(c[o + 3]) << 24)
  34.  
  35.  
  36. def ol16(i):
  37.     return chr(i & 255) + chr(i >> 8 & 255)
  38.  
  39.  
  40. def ol32(i):
  41.     return chr(i & 255) + chr(i >> 8 & 255) + chr(i >> 16 & 255) + chr(i >> 24 & 255)
  42.  
  43.  
  44. def ib16(c, o = 0):
  45.     return ord(c[o + 1]) + (ord(c[o]) << 8)
  46.  
  47.  
  48. def ib32(c, o = 0):
  49.     return ord(c[o + 3]) + (ord(c[o + 2]) << 8) + (ord(c[o + 1]) << 16) + (ord(c[o]) << 24)
  50.  
  51. IMAGEWIDTH = 256
  52. IMAGELENGTH = 257
  53. BITSPERSAMPLE = 258
  54. COMPRESSION = 259
  55. PHOTOMETRIC_INTERPRETATION = 262
  56. FILLORDER = 266
  57. IMAGEDESCRIPTION = 270
  58. STRIPOFFSETS = 273
  59. SAMPLESPERPIXEL = 277
  60. ROWSPERSTRIP = 278
  61. STRIPBYTECOUNTS = 279
  62. X_RESOLUTION = 282
  63. Y_RESOLUTION = 283
  64. PLANAR_CONFIGURATION = 284
  65. RESOLUTION_UNIT = 296
  66. SOFTWARE = 305
  67. DATE_TIME = 306
  68. ARTIST = 315
  69. PREDICTOR = 317
  70. COLORMAP = 320
  71. EXTRASAMPLES = 338
  72. SAMPLEFORMAT = 339
  73. JPEGTABLES = 347
  74. COPYRIGHT = 33432
  75. IPTC_NAA_CHUNK = 33723
  76. PHOTOSHOP_CHUNK = 34377
  77. COMPRESSION_INFO = {
  78.     1: 'raw',
  79.     2: 'tiff_ccitt',
  80.     3: 'group3',
  81.     4: 'group4',
  82.     5: 'tiff_lzw',
  83.     6: 'tiff_jpeg',
  84.     7: 'jpeg',
  85.     32771: 'tiff_raw_16',
  86.     32773: 'packbits' }
  87. OPEN_INFO = {
  88.     (0, 1, 1, (1,), ()): ('1', '1;I'),
  89.     (0, 1, 2, (1,), ()): ('1', '1;IR'),
  90.     (0, 1, 1, (8,), ()): ('L', 'L;I'),
  91.     (0, 1, 2, (8,), ()): ('L', 'L;IR'),
  92.     (1, 1, 1, (1,), ()): ('1', '1'),
  93.     (1, 1, 2, (1,), ()): ('1', '1;R'),
  94.     (1, 1, 1, (8,), ()): ('L', 'L'),
  95.     (1, 1, 1, (8, 8), (2,)): ('LA', 'LA'),
  96.     (1, 1, 2, (8,), ()): ('L', 'L;R'),
  97.     (1, 1, 1, (16,), ()): ('I;16', 'I;16'),
  98.     (1, 2, 1, (16,), ()): ('I;16S', 'I;16S'),
  99.     (1, 2, 1, (32,), ()): ('I', 'I;32S'),
  100.     (1, 3, 1, (32,), ()): ('F', 'F;32F'),
  101.     (2, 1, 1, (8, 8, 8), ()): ('RGB', 'RGB'),
  102.     (2, 1, 2, (8, 8, 8), ()): ('RGB', 'RGB;R'),
  103.     (2, 1, 1, (8, 8, 8, 8), (0,)): ('RGBX', 'RGBX'),
  104.     (2, 1, 1, (8, 8, 8, 8), (1,)): ('RGBA', 'RGBa'),
  105.     (2, 1, 1, (8, 8, 8, 8), (2,)): ('RGBA', 'RGBA'),
  106.     (2, 1, 1, (8, 8, 8, 8), (999,)): ('RGBA', 'RGBA'),
  107.     (3, 1, 1, (1,), ()): ('P', 'P;1'),
  108.     (3, 1, 2, (1,), ()): ('P', 'P;1R'),
  109.     (3, 1, 1, (2,), ()): ('P', 'P;2'),
  110.     (3, 1, 2, (2,), ()): ('P', 'P;2R'),
  111.     (3, 1, 1, (4,), ()): ('P', 'P;4'),
  112.     (3, 1, 2, (4,), ()): ('P', 'P;4R'),
  113.     (3, 1, 1, (8,), ()): ('P', 'P'),
  114.     (3, 1, 1, (8, 8), (2,)): ('PA', 'PA'),
  115.     (3, 1, 2, (8,), ()): ('P', 'P;R'),
  116.     (5, 1, 1, (8, 8, 8, 8), ()): ('CMYK', 'CMYK'),
  117.     (6, 1, 1, (8, 8, 8), ()): ('YCbCr', 'YCbCr'),
  118.     (8, 1, 1, (8, 8, 8), ()): ('LAB', 'LAB') }
  119. PREFIXES = [
  120.     'MM\x00*',
  121.     'II*\x00',
  122.     'II\xbc\x00']
  123.  
  124. def _accept(prefix):
  125.     return prefix[:4] in PREFIXES
  126.  
  127.  
  128. class ImageFileDirectory:
  129.     
  130.     def __init__(self, prefix = 'II'):
  131.         self.prefix = prefix[:2]
  132.         if self.prefix == 'MM':
  133.             self.i16 = ib16
  134.             self.i32 = ib32
  135.         elif self.prefix == 'II':
  136.             self.i16 = il16
  137.             self.i32 = il32
  138.             self.o16 = ol16
  139.             self.o32 = ol32
  140.         else:
  141.             raise SyntaxError('not a TIFF IFD')
  142.         (self.prefix == 'MM').reset()
  143.  
  144.     
  145.     def reset(self):
  146.         self.tags = { }
  147.         self.tagdata = { }
  148.         self.next = None
  149.  
  150.     
  151.     def keys(self):
  152.         return self.tagdata.keys() + self.tags.keys()
  153.  
  154.     
  155.     def items(self):
  156.         items = self.tags.items()
  157.         for tag in self.tagdata.keys():
  158.             items.append((tag, self[tag]))
  159.         
  160.         return items
  161.  
  162.     
  163.     def __len__(self):
  164.         return len(self.tagdata) + len(self.tags)
  165.  
  166.     
  167.     def __getitem__(self, tag):
  168.         
  169.         try:
  170.             return self.tags[tag]
  171.         except KeyError:
  172.             (type, data) = self.tagdata[tag]
  173.             (size, handler) = self.load_dispatch[type]
  174.             self.tags[tag] = data = handler(self, data)
  175.             del self.tagdata[tag]
  176.             return data
  177.  
  178.  
  179.     
  180.     def get(self, tag, default = None):
  181.         
  182.         try:
  183.             return self[tag]
  184.         except KeyError:
  185.             return default
  186.  
  187.  
  188.     
  189.     def getscalar(self, tag, default = None):
  190.         
  191.         try:
  192.             value = self[tag]
  193.             if len(value) != 1:
  194.                 if tag == SAMPLEFORMAT:
  195.                     raise KeyError
  196.                 tag == SAMPLEFORMAT
  197.                 raise ValueError, 'not a scalar'
  198.             len(value) != 1
  199.             return value[0]
  200.         except KeyError:
  201.             if default is None:
  202.                 raise 
  203.             default is None
  204.             return default
  205.  
  206.  
  207.     
  208.     def has_key(self, tag):
  209.         if not self.tags.has_key(tag):
  210.             pass
  211.         return self.tagdata.has_key(tag)
  212.  
  213.     
  214.     def __setitem__(self, tag, value):
  215.         if type(value) is not type(()):
  216.             value = (value,)
  217.         
  218.         self.tags[tag] = value
  219.  
  220.     load_dispatch = { }
  221.     
  222.     def load_byte(self, data):
  223.         l = []
  224.         for i in range(len(data)):
  225.             l.append(ord(data[i]))
  226.         
  227.         return tuple(l)
  228.  
  229.     load_dispatch[1] = (1, load_byte)
  230.     
  231.     def load_string(self, data):
  232.         if data[-1:] == '\x00':
  233.             data = data[:-1]
  234.         
  235.         return data
  236.  
  237.     load_dispatch[2] = (1, load_string)
  238.     
  239.     def load_short(self, data):
  240.         l = []
  241.         for i in range(0, len(data), 2):
  242.             l.append(self.i16(data, i))
  243.         
  244.         return tuple(l)
  245.  
  246.     load_dispatch[3] = (2, load_short)
  247.     
  248.     def load_long(self, data):
  249.         l = []
  250.         for i in range(0, len(data), 4):
  251.             l.append(self.i32(data, i))
  252.         
  253.         return tuple(l)
  254.  
  255.     load_dispatch[4] = (4, load_long)
  256.     
  257.     def load_rational(self, data):
  258.         l = []
  259.         for i in range(0, len(data), 8):
  260.             l.append((self.i32(data, i), self.i32(data, i + 4)))
  261.         
  262.         return tuple(l)
  263.  
  264.     load_dispatch[5] = (8, load_rational)
  265.     
  266.     def load_float(self, data):
  267.         a = array.array('f', data)
  268.         if self.prefix != byteorder:
  269.             a.byteswap()
  270.         
  271.         return tuple(a)
  272.  
  273.     load_dispatch[11] = (4, load_float)
  274.     
  275.     def load_double(self, data):
  276.         a = array.array('d', data)
  277.         if self.prefix != byteorder:
  278.             a.byteswap()
  279.         
  280.         return tuple(a)
  281.  
  282.     load_dispatch[12] = (8, load_double)
  283.     
  284.     def load_undefined(self, data):
  285.         return data
  286.  
  287.     load_dispatch[7] = (1, load_undefined)
  288.     
  289.     def load(self, fp):
  290.         self.reset()
  291.         i16 = self.i16
  292.         i32 = self.i32
  293.         for i in range(i16(fp.read(2))):
  294.             ifd = fp.read(12)
  295.             tag = i16(ifd)
  296.             typ = i16(ifd, 2)
  297.             if Image.DEBUG:
  298.                 import TiffTags
  299.                 tagname = TiffTags.TAGS.get(tag, 'unknown')
  300.                 typname = TiffTags.TYPES.get(typ, 'unknown')
  301.                 print 'tag: %s (%d)' % (tagname, tag), '- type: %s (%d)' % (typname, typ),
  302.             
  303.             
  304.             try:
  305.                 dispatch = self.load_dispatch[typ]
  306.             except KeyError:
  307.                 if Image.DEBUG:
  308.                     print '- unsupported type', typ
  309.                     continue
  310.                 continue
  311.  
  312.             (size, handler) = dispatch
  313.             size = size * i32(ifd, 4)
  314.             if size > 4:
  315.                 here = fp.tell()
  316.                 fp.seek(i32(ifd, 8))
  317.                 data = ImageFile._safe_read(fp, size)
  318.                 fp.seek(here)
  319.             else:
  320.                 data = ifd[8:8 + size]
  321.             if len(data) != size:
  322.                 raise IOError, 'not enough data'
  323.             len(data) != size
  324.             self.tagdata[tag] = (typ, data)
  325.             if Image.DEBUG:
  326.                 if tag in (COLORMAP, IPTC_NAA_CHUNK, PHOTOSHOP_CHUNK):
  327.                     print '- value: <table: %d bytes>' % size
  328.                 else:
  329.                     print '- value:', self[tag]
  330.             tag in (COLORMAP, IPTC_NAA_CHUNK, PHOTOSHOP_CHUNK)
  331.         
  332.         self.next = i32(fp.read(4))
  333.  
  334.     
  335.     def save(self, fp):
  336.         o16 = self.o16
  337.         o32 = self.o32
  338.         fp.write(o16(len(self.tags)))
  339.         tags = self.tags.items()
  340.         tags.sort()
  341.         directory = []
  342.         append = directory.append
  343.         offset = fp.tell() + len(self.tags) * 12 + 4
  344.         stripoffsets = None
  345.         for tag, value in tags:
  346.             if Image.DEBUG:
  347.                 import TiffTags
  348.                 tagname = TiffTags.TAGS.get(tag, 'unknown')
  349.                 print 'save: %s (%d)' % (tagname, tag), '- value:', value
  350.             
  351.             if type(value[0]) is type(''):
  352.                 typ = 2
  353.                 data = value = string.join(value, '\x00') + '\x00'
  354.             elif tag == STRIPOFFSETS:
  355.                 stripoffsets = len(directory)
  356.                 typ = 4
  357.             elif tag in (X_RESOLUTION, Y_RESOLUTION):
  358.                 typ = 5
  359.             else:
  360.                 typ = 3
  361.                 for v in value:
  362.                     if v >= 65536:
  363.                         typ = 4
  364.                         continue
  365.                 
  366.             if typ == 3:
  367.                 data = string.join(map(o16, value), '')
  368.             else:
  369.                 data = string.join(map(o32, value), '')
  370.             if len(data) == 4:
  371.                 append((tag, typ, len(value), data, ''))
  372.                 continue
  373.             if len(data) < 4:
  374.                 append((tag, typ, len(value), data + (4 - len(data)) * '\x00', ''))
  375.                 continue
  376.             count = len(value)
  377.             if typ == 5:
  378.                 count = count / 2
  379.             
  380.             append((tag, typ, count, o32(offset), data))
  381.             offset = offset + len(data)
  382.             if offset & 1:
  383.                 offset = offset + 1
  384.                 continue
  385.         
  386.         if stripoffsets is not None:
  387.             (tag, typ, count, value, data) = directory[stripoffsets]
  388.             if not not data:
  389.                 raise AssertionError, 'multistrip support not yet implemented'
  390.             value = o32(self.i32(value) + offset)
  391.             directory[stripoffsets] = (tag, typ, count, value, data)
  392.         
  393.         for tag, typ, count, value, data in directory:
  394.             if Image.DEBUG > 1:
  395.                 print tag, typ, count, repr(value), repr(data)
  396.             
  397.             fp.write(o16(tag) + o16(typ) + o32(count) + value)
  398.         
  399.         fp.write('\x00\x00\x00\x00')
  400.         for tag, typ, count, value, data in directory:
  401.             fp.write(data)
  402.             if len(data) & 1:
  403.                 fp.write('\x00')
  404.                 continue
  405.         
  406.         return offset
  407.  
  408.  
  409.  
  410. class TiffImageFile(ImageFile.ImageFile):
  411.     format = 'TIFF'
  412.     format_description = 'Adobe TIFF'
  413.     
  414.     def _open(self):
  415.         '''Open the first image in a TIFF file'''
  416.         ifh = self.fp.read(8)
  417.         if ifh[:4] not in PREFIXES:
  418.             raise SyntaxError, 'not a TIFF file'
  419.         ifh[:4] not in PREFIXES
  420.         self.tag = self.ifd = ImageFileDirectory(ifh[:2])
  421.         self._TiffImageFile__first = self._TiffImageFile__next = self.ifd.i32(ifh, 4)
  422.         self._TiffImageFile__frame = -1
  423.         self._TiffImageFile__fp = self.fp
  424.         self._seek(0)
  425.  
  426.     
  427.     def seek(self, frame):
  428.         '''Select a given frame as current image'''
  429.         if frame < 0:
  430.             frame = 0
  431.         
  432.         self._seek(frame)
  433.  
  434.     
  435.     def tell(self):
  436.         '''Return the current frame number'''
  437.         return self._tell()
  438.  
  439.     
  440.     def _seek(self, frame):
  441.         self.fp = self._TiffImageFile__fp
  442.         if frame < self._TiffImageFile__frame:
  443.             self._TiffImageFile__frame = -1
  444.             self._TiffImageFile__next = self._TiffImageFile__first
  445.         
  446.         while self._TiffImageFile__frame < frame:
  447.             if not self._TiffImageFile__next:
  448.                 raise EOFError, 'no more images in TIFF file'
  449.             self._TiffImageFile__next
  450.             self.fp.seek(self._TiffImageFile__next)
  451.             self.tag.load(self.fp)
  452.             self._TiffImageFile__next = self.tag.next
  453.             self._TiffImageFile__frame = self._TiffImageFile__frame + 1
  454.         self._setup()
  455.  
  456.     
  457.     def _tell(self):
  458.         return self._TiffImageFile__frame
  459.  
  460.     
  461.     def _decoder(self, rawmode, layer):
  462.         '''Setup decoder contexts'''
  463.         args = None
  464.         if rawmode == 'RGB' and self._planar_configuration == 2:
  465.             rawmode = rawmode[layer]
  466.         
  467.         compression = self._compression
  468.         if compression == 'raw':
  469.             args = (rawmode, 0, 1)
  470.         elif compression == 'jpeg':
  471.             args = (rawmode, '')
  472.             if self.tag.has_key(JPEGTABLES):
  473.                 self.tile_prefix = self.tag[JPEGTABLES]
  474.             
  475.         elif compression == 'packbits':
  476.             args = rawmode
  477.         elif compression == 'tiff_lzw':
  478.             args = rawmode
  479.             if self.tag.has_key(317):
  480.                 self.decoderconfig = (self.tag[PREDICTOR][0],)
  481.             
  482.         
  483.         return args
  484.  
  485.     
  486.     def _setup(self):
  487.         '''Setup this image object based on current tags'''
  488.         if self.tag.has_key(48129):
  489.             raise IOError, 'Windows Media Photo files not yet supported'
  490.         self.tag.has_key(48129)
  491.         getscalar = self.tag.getscalar
  492.         self._compression = COMPRESSION_INFO[getscalar(COMPRESSION, 1)]
  493.         self._planar_configuration = getscalar(PLANAR_CONFIGURATION, 1)
  494.         photo = getscalar(PHOTOMETRIC_INTERPRETATION, 0)
  495.         fillorder = getscalar(FILLORDER, 1)
  496.         if Image.DEBUG:
  497.             print '*** Summary ***'
  498.             print '- compression:', self._compression
  499.             print '- photometric_interpretation:', photo
  500.             print '- planar_configuration:', self._planar_configuration
  501.             print '- fill_order:', fillorder
  502.         
  503.         xsize = getscalar(IMAGEWIDTH)
  504.         ysize = getscalar(IMAGELENGTH)
  505.         self.size = (xsize, ysize)
  506.         if Image.DEBUG:
  507.             print '- size:', self.size
  508.         
  509.         format = getscalar(SAMPLEFORMAT, 1)
  510.         key = (photo, format, fillorder, self.tag.get(BITSPERSAMPLE, (1,)), self.tag.get(EXTRASAMPLES, ()))
  511.         if Image.DEBUG:
  512.             print 'format key:', key
  513.         
  514.         
  515.         try:
  516.             (self.mode, rawmode) = OPEN_INFO[key]
  517.         except KeyError:
  518.             if Image.DEBUG:
  519.                 print '- unsupported format'
  520.             
  521.             raise SyntaxError, 'unknown pixel mode'
  522.  
  523.         if Image.DEBUG:
  524.             print '- raw mode:', rawmode
  525.             print '- pil mode:', self.mode
  526.         
  527.         self.info['compression'] = self._compression
  528.         xdpi = getscalar(X_RESOLUTION, (1, 1))
  529.         ydpi = getscalar(Y_RESOLUTION, (1, 1))
  530.         if xdpi and ydpi:
  531.             if not xdpi[1]:
  532.                 pass
  533.             xdpi = xdpi[0] / 1
  534.             if not ydpi[1]:
  535.                 pass
  536.             ydpi = ydpi[0] / 1
  537.             unit = getscalar(RESOLUTION_UNIT, 1)
  538.             if unit == 1:
  539.                 self.info['aspect'] = (xdpi, ydpi)
  540.             elif unit == 2:
  541.                 self.info['dpi'] = (xdpi, ydpi)
  542.             elif unit == 3:
  543.                 self.info['dpi'] = (xdpi * 0.393701, ydpi * 0.393701)
  544.             
  545.         
  546.         x = y = l = 0
  547.         self.tile = []
  548.         if self.tag.has_key(STRIPOFFSETS):
  549.             h = getscalar(ROWSPERSTRIP, ysize)
  550.             w = self.size[0]
  551.             a = None
  552.             for o in self.tag[STRIPOFFSETS]:
  553.                 if not a:
  554.                     a = self._decoder(rawmode, l)
  555.                 
  556.                 self.tile.append((self._compression, (0, min(y, ysize), w, min(y + h, ysize)), o, a))
  557.                 y = y + h
  558.                 if y >= self.size[1]:
  559.                     x = y = 0
  560.                     l = l + 1
  561.                     a = None
  562.                     continue
  563.             
  564.         elif self.tag.has_key(324):
  565.             w = getscalar(322)
  566.             h = getscalar(323)
  567.             a = None
  568.             for o in self.tag[324]:
  569.                 if not a:
  570.                     a = self._decoder(rawmode, l)
  571.                 
  572.                 self.tile.append((self._compression, (x, y, x + w, y + h), o, a))
  573.                 x = x + w
  574.                 if x >= self.size[0]:
  575.                     x = 0
  576.                     y = y + h
  577.                     if y >= self.size[1]:
  578.                         x = y = 0
  579.                         l = l + 1
  580.                         a = None
  581.                     
  582.                 y >= self.size[1]
  583.             
  584.         elif Image.DEBUG:
  585.             print '- unsupported data organization'
  586.         
  587.         raise SyntaxError('unknown data organization')
  588.         if self.mode == 'P':
  589.             palette = map((lambda a: chr(a / 256)), self.tag[COLORMAP])
  590.             self.palette = ImagePalette.raw('RGB;L', string.join(palette, ''))
  591.         
  592.  
  593.  
  594. SAVE_INFO = {
  595.     '1': ('1', 1, 1, (1,), None),
  596.     'L': ('L', 1, 1, (8,), None),
  597.     'LA': ('LA', 1, 1, (8, 8), 2),
  598.     'P': ('P', 3, 1, (8,), None),
  599.     'PA': ('PA', 3, 1, (8, 8), 2),
  600.     'I': ('I;32S', 1, 2, (32,), None),
  601.     'I;16': ('I;16', 1, 1, (16,), None),
  602.     'I;16S': ('I;16S', 1, 2, (16,), None),
  603.     'F': ('F;32F', 1, 3, (32,), None),
  604.     'RGB': ('RGB', 2, 1, (8, 8, 8), None),
  605.     'RGBX': ('RGBX', 2, 1, (8, 8, 8, 8), 0),
  606.     'RGBA': ('RGBA', 2, 1, (8, 8, 8, 8), 2),
  607.     'CMYK': ('CMYK', 5, 1, (8, 8, 8, 8), None),
  608.     'YCbCr': ('YCbCr', 6, 1, (8, 8, 8), None),
  609.     'LAB': ('LAB', 8, 1, (8, 8, 8), None) }
  610.  
  611. def _cvt_res(value):
  612.     if type(value) in (type([]), type(())):
  613.         if not len(value) % 2 == 0:
  614.             raise AssertionError
  615.         return value
  616.     if type(value) == type(1):
  617.         return (value, 1)
  618.     value = float(value)
  619.     return (int(value * 65536), 65536)
  620.  
  621.  
  622. def _save(im, fp, filename):
  623.     
  624.     try:
  625.         (rawmode, photo, format, bits, extra) = SAVE_INFO[im.mode]
  626.     except KeyError:
  627.         raise IOError, 'cannot write mode %s as TIFF' % im.mode
  628.  
  629.     ifd = ImageFileDirectory()
  630.     fp.write(ifd.prefix + ifd.o16(42) + ifd.o32(8))
  631.     ifd[IMAGEWIDTH] = im.size[0]
  632.     ifd[IMAGELENGTH] = im.size[1]
  633.     if hasattr(im, 'tag'):
  634.         for key in (RESOLUTION_UNIT, X_RESOLUTION, Y_RESOLUTION):
  635.             if im.tag.tagdata.has_key(key):
  636.                 ifd[key] = im.tag.tagdata.get(key)
  637.                 continue
  638.         
  639.     
  640.     if im.encoderinfo.has_key('description'):
  641.         ifd[IMAGEDESCRIPTION] = im.encoderinfo['description']
  642.     
  643.     if im.encoderinfo.has_key('resolution'):
  644.         ifd[X_RESOLUTION] = ifd[Y_RESOLUTION] = _cvt_res(im.encoderinfo['resolution'])
  645.     
  646.     if im.encoderinfo.has_key('x resolution'):
  647.         ifd[X_RESOLUTION] = _cvt_res(im.encoderinfo['x resolution'])
  648.     
  649.     if im.encoderinfo.has_key('y resolution'):
  650.         ifd[Y_RESOLUTION] = _cvt_res(im.encoderinfo['y resolution'])
  651.     
  652.     if im.encoderinfo.has_key('resolution unit'):
  653.         unit = im.encoderinfo['resolution unit']
  654.         if unit == 'inch':
  655.             ifd[RESOLUTION_UNIT] = 2
  656.         elif unit == 'cm' or unit == 'centimeter':
  657.             ifd[RESOLUTION_UNIT] = 3
  658.         else:
  659.             ifd[RESOLUTION_UNIT] = 1
  660.     
  661.     if im.encoderinfo.has_key('software'):
  662.         ifd[SOFTWARE] = im.encoderinfo['software']
  663.     
  664.     if im.encoderinfo.has_key('date time'):
  665.         ifd[DATE_TIME] = im.encoderinfo['date time']
  666.     
  667.     if im.encoderinfo.has_key('artist'):
  668.         ifd[ARTIST] = im.encoderinfo['artist']
  669.     
  670.     if im.encoderinfo.has_key('copyright'):
  671.         ifd[COPYRIGHT] = im.encoderinfo['copyright']
  672.     
  673.     dpi = im.encoderinfo.get('dpi')
  674.     if dpi:
  675.         ifd[RESOLUTION_UNIT] = 2
  676.         ifd[X_RESOLUTION] = _cvt_res(dpi[0])
  677.         ifd[Y_RESOLUTION] = _cvt_res(dpi[1])
  678.     
  679.     if bits != (1,):
  680.         ifd[BITSPERSAMPLE] = bits
  681.         if len(bits) != 1:
  682.             ifd[SAMPLESPERPIXEL] = len(bits)
  683.         
  684.     
  685.     if extra is not None:
  686.         ifd[EXTRASAMPLES] = extra
  687.     
  688.     if format != 1:
  689.         ifd[SAMPLEFORMAT] = format
  690.     
  691.     ifd[PHOTOMETRIC_INTERPRETATION] = photo
  692.     if im.mode == 'P':
  693.         lut = im.im.getpalette('RGB', 'RGB;L')
  694.         ifd[COLORMAP] = tuple(map((lambda v: ord(v) * 256), lut))
  695.     
  696.     stride = len(bits) * ((im.size[0] * bits[0] + 7) / 8)
  697.     ifd[ROWSPERSTRIP] = im.size[1]
  698.     ifd[STRIPBYTECOUNTS] = stride * im.size[1]
  699.     ifd[STRIPOFFSETS] = 0
  700.     ifd[COMPRESSION] = 1
  701.     offset = ifd.save(fp)
  702.     ImageFile._save(im, fp, [
  703.         ('raw', (0, 0) + im.size, offset, (rawmode, stride, 1))])
  704.  
  705. Image.register_open('TIFF', TiffImageFile, _accept)
  706. Image.register_save('TIFF', _save)
  707. Image.register_extension('TIFF', '.tif')
  708. Image.register_extension('TIFF', '.tiff')
  709. Image.register_mime('TIFF', 'image/tiff')
  710.